package online.longzipeng.mywebdemo.mq.consumer;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @Author: lzp
 * @description: 发布订阅-主题模式
 * 该模式 与发布订阅的直连模式差不多，区别在于交换机是按照 规则匹配【对应表达式】
 * (星号 * ) 用来表示一个单词 (必须出现的)
 * (井号 # ) 用来表示任意数量（零个或多个）单词
 * 举例：
 * 队列Q1 绑定键为*.TT.*
 * 队列Q2绑定键为TT.#
 * 如果一条消息携带的路由键为 A.TT.B，那么队列Q1将会收到
 * 如果一条消息携带的路由键为TT.AA.BB，那么队列Q2将会收到
 * @Date: 2024/1/14
 */
@Component
public class TopicsConsumer {


	//队列名称常量
	public static final String QUEUE_NAME1 = "topic_queue1";
	public static final String QUEUE_NAME2 = "topic_queue2";
	//交换机名称常量
	public static final String EXCHANGE_NAME = "topic_exchange";

	/** ======================= 订阅模式， 主题，一个扇形交换机，两个消费队列 =========================*/

	/**
	 * 声明队列 Queue
	 */
	@Bean
	public Queue topicQueue1() {
		return new Queue(QUEUE_NAME1, true, false, false, null);
	}

	/**
	 * 声明队列 Queue
	 */
	@Bean
	public Queue topicQueue2() {
		return new Queue(QUEUE_NAME2, true, false, false, null);
	}


	/**
	 * 声明交换机
	 */
	@Bean
	TopicExchange topicExchange() {
		return new TopicExchange(EXCHANGE_NAME, true, false, null);
	}

	/**
	 * 交换机队列绑定
	 */
	@Bean
	Binding bindingTopicExchange1(@Autowired Queue topicQueue1, @Autowired TopicExchange topicExchange) {
		return BindingBuilder.bind(topicQueue1).to(topicExchange).with("*.TT.*");
	}

	@Bean
	Binding bindingTopicExchange2(@Autowired Queue topicQueue2, @Autowired TopicExchange topicExchange) {
		return BindingBuilder.bind(topicQueue2).to(topicExchange).with("TT.#");
	}

	/**
	 * 订阅模式， 主题，两个消费者
	 */
	@RabbitListener(queues = "topic_queue1")
	public void receive1(String msgData, Message message, Channel channel) throws IOException {
		channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		System.out.println("topic_queue1消费者收到消息  : " + msgData);
	}

	@RabbitListener(queues = "topic_queue2")
	public void receive2(String msgData, Message message, Channel channel) throws IOException {
		channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		System.out.println("topic_queue2消费者收到消息  : " + msgData);
	}

}
